 FLI utility module
 ------------------
 This module provides a number of SWIs to manipulate FLI files. A FLI
file can be loaded and decompressed frame by frame.

 The module can handle multiple files at once. The individual files are
addressed using a handle.
 The module requires 64 bytes private workspace for each file. This must
be provided by the application.


 Very boring legal notice
 ------------------------
 The FLI module is Public Domain, and is provided 'as is'. The author cannot
accept any liability for any damage or loss of any kind as a result of the use
of this program.
 You may include the module with commercial programs as long as you include
this file.

 Henrik Bjerregaard Pedersen
 Bellahoejvej 126 st. th.
 DK-2720 Vanloese
 Denmark

 email: henrik@login.dknet.dk


 History
 =======
 1.00:  First release.
        Only FLI files (not FLIC).
        Only 18 bit palette.

 1.01:  FLIC files supported.
        Also supports 24 bit palettes.
        Support of SS2 compression.

 1.02:  Small bug removed.

 1.03:  The frames can be loaded one by one.


 In use
 ======

 To decompress and display a FLI file, the following piece of code will do:

  10 MODE 21
  20 File$=""
  30 DIM Spr% 70000, Work% 64, ColTable% 256
  40 Spr%!0=70000:Spr%!4=0
  50 Spr%!8=16:Spr%!12=16
  60 SYS"OS_SpriteOp",256+15,Spr%,"frame",0,320,200,21
  70 SYS"OS_SpriteOp",256+37,Spr%,"frame",&80000000
  80 SYS"FLI_LoadFile",Work%,File$,0 TO Handle%
  90 Frame%=0
 100 REPEAT
 110  SYS"FLI_Decompress",Handle%,Frame%,Spr%+2108 TO Palette%,Frame%
 120  IF Palette%>0 THEN
 130   SYS"FLI_ReadPalette",Palette%,Spr%+60,0
 140   SYS"ColourTrans_SelectTable",Spr%,"frame",-1,-1,ColTable%
 150  ENDIF
 160  SYS"OS_SpriteOp",256+52,Spr%,"frame",0,0,0,0,ColTable%
 170 UNTIL Frame%=0
 180 SYS"FLI_Kill",Handle%
 190 QUIT

 Of course, you need to alter the filename in line 20.

 To decompress and display a FLIC file from disc:

  10 MODE 21
  20 File$=""
  30 DIM Work% 16584, ColTable% 256
  40 SYS"FLI_LoadFile",Work%,File$,&4E414353 TO Handle%,Max%
  50 DIM Buffer% Max%
  60 SYS"FLI_Control",Work%,-1,Buffer% TO Frames%,,Speed%,X%,Y%
  70 DIM Sprite% 4096+X%*Y%
  80 Spr%!0=4096+X%*Y%:Spr%!4=0
  90 Spr%!8=16:Spr%!12=16
 100 SYS"OS_SpriteOp",256+15,Spr%,"frame",0,X%,Y%,21
 110 SYS"OS_SpriteOp",256+37,Spr%,"frame",&80000000
 120 Frame%=0
 130 REPEAT
 140  SYS"FLI_Decompress",Handle%,Frame%,Spr%+2108 TO Palette%,Frame%
 150  IF Palette%>0 THEN
 160   SYS"FLI_ReadPalette",Palette%,Spr%+60,0
 170   SYS"ColourTrans_SelectTable",Spr%,"frame",-1,-1,ColTable%
 180  ENDIF
 190  SYS"OS_SpriteOp",256+52,Spr%,"frame",0,0,0,0,ColTable%
 200  Key%=INKEY 0
 210 UNTIL Key%=32
 220 SYS"FLI_Kill",Handle%
 230 QUIT

 SWIs
 ====

 SWI FLI_LoadFile (&D9740)
 -------------------------
 This call loads a FLI file into memory. The memory can be allocated by the
parent application or it can be allocated by the module itself, in which case
it'll be taken from the RMA.
 If memory is tight, the file can be loaded frame by frame. This is done by
setting R2 = &4E414353 ("SCAN") on entry, in which case the size of the
workspace (R0) must be 16584 bytes. Please notice that the file is opened
by this call, and closed by SWI FLI_Kill.

 Entry
        R0  =>  Workspace for the file, 64 or 16548 bytes (if R2 = "SCAN")
        R1  =>  Filename or 0 if the file has already been loaded into the
                buffer in R2
        R2  =>  Block to hold the file (must be wordaligned)
                or 0 (let the module allocate the space)
                or &4E414353 (= "SCAN") to load the file frame by frame
        R3  =   File size (if R1 = 0)
 Exit
        R0  =   Handle for the file
        R1  =   Size of largest frame (if R2 = &4E414353 on entry)


 SWI FLI_Control (&D9741)
 ------------------------
 This call sets the flags for the file and returns various info about it.

 Entry
        R0  =   Handle
        R1  =   Flags
                       bit 0 set => R2 holds buffer for compressed frames
                or -1 to read old settings.
        R2  =>  If bit 0 of R1 set => Buffer for compressed frames (ignored
                 if SWI FLI_LoadFile wasn't called with R2 = &4E414353)
 Exit
        R0  =   Number of frames in the file (N)
        R1  =   Old flags
        R2  =   Playback speed (centiseconds per frame)
        R3  =   Size X in pixels
        R4  =   Size Y in pixels


 SWI FLI_Decompress (&D9742)
 ---------------------------
 This call decompresses a single frame. It returns a pointer to a compressed
palette structure in R0 if the palette has changed since last.

 Entry
        R0  =   Handle
        R1  =   Frame number (0 .. N-1). Initally set to 0.
        R2  =>  Frame buffer (the frame buffer MUST be wordaligned)
 Exit
        R0  =   0 (OK) or palette pointer (see FLI_ReadPalette)
        R1  =   Next frame number
        R2  =   Offset in file of frame in framebuffer


 SWI FLI_Kill (&D9743)
 ---------------------
 This call discards a file and releases the workspace it has used.

 Entry
        R0  =>  Handle


 SWI FLI_ReadPalette (&D9744)
 ----------------------------
 This calls unpacks a palette.

 Entry
        R0  =>  Compressed palette (as returned by SWI FLI_Decompress)
        R1  =>  Buffer for palette
        R2  =   Palette type
                0 = 256 entry sprite palette (double word entries)
                1 = 256 entry normal palette (single word entries)
                2 = raw palette (3 bytes per entry)
